/* 
 * A layout is a minimalistic representation of the tilemap.
 * In the process of converting a dungeon graph to an actual
 * tilemap, it is first converted to a "layout", which is
 * much simpler than the game-time map representation in
 * terms of stored information.
 */

#ifndef LAYOUT_H_
#define LAYOUT_H_

#include <stdint.h>
#include <stdbool.h>
#include "util/rect.h"

// max. roots / branches in a single segment.
// also affects branching capacity of single rooms.
#define MAX_ROOTS 8
#define MAX_BRANCHES 8

typedef enum { TRAVERSAL_STAIRS, TRAVERSAL_TELEPORTER } TraversalType;

typedef struct {
	TraversalType type;
	Coord anchor[2];    // End points of the traversal
} Traversal;

typedef struct {
	Rect area;
	Coord entry[MAX_ROOTS];    // End points of the traversal
	int n_entries;
	Coord exit[MAX_BRANCHES];    // End points of the traversal
	int n_exits;
} Room;

typedef struct {
	bool room;  // or not room (this is not a room index)
	bool floor; // or wall
} TileLayout;

typedef struct {
	TileLayout* tile;
	int tiles_size;
	int width;            // Width of one map layer
	int height;           // Height of one map layer
	int layers;           // # of map layers
	
	Traversal* traversal; // Stairs and teleporters
	int traversals_size;
	int n_traversals;
	
	Room* room;           // Rects include room walls
	int rooms_size;
	int n_rooms;
} Layout;

/* allocates & frees layout resources */
void layout_init (Layout* layout, int width, int height, int layers, 
                  int traversals_size, int rooms_size);
void layout_cleanup (Layout* layout);

/* if necessary, resizes the layout to include at
 * least the given number of layers, possibly more */
void layout_extend (Layout* layout, int layers);

/* sets regions of tiles to floor */
void layout_floor_rect (Layout* layout, Rect* rect);

/* adds a traversal to the list */
void layout_add_traversal (Layout* layout, TraversalType type, 
                           Coord anchor[2]);

/* marks an area as room and sets room bits in the rect area.
 * returns the index of the new room in the rooms array as handle.
 * the new room has no entries and no exits. */
int layout_add_room (Layout* layout, Rect* area);

/* inserts an entry into a room */
void layout_add_room_entry (Layout* layout, int room, Coord entry);

/* inserts an exit into a room */
void layout_add_room_exit (Layout* layout, int room, Coord exit);

#endif /* LAYOUT_H_ */
